home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Sample Code / Devices / RAMDisk 1.4d5 / Documentation / Changes in 1.2 < prev    next >
Encoding:
Text File  |  1997-03-07  |  4.8 KB  |  68 lines  |  [TEXT/ttxt]

  1. Changes in 1.2
  2. __________________________________________________
  3.  
  4. • DriverInstall (suggested by John Wang)
  5. Instead of creating a AuxDCE record, we were creating a DCtlEntry. Because the record is smaller, the dCtlSlot field is garbage and causes _SUpdateSrt to be called when the driver is closed.
  6. __________________________________________________
  7.  
  8. • DriverRemove (suggested by Mike Wiese)
  9. DriverRemove should not be disposing the driverhandle stored in dCltDriver, since the install routine calls ReleaseResource or DisposHandle as appropriate. Plus, if it's pointer based as it should be, disposeHandle won't work.
  10. __________________________________________________
  11.  
  12. • DriverInstall (suggested by François Grieu)
  13. The Sample RAMDisk is installed with the dRamBased bit set.  Therefore, calls to this driver cause the DCtlEntry to be passed to _RecoverHandle and _HLock, and the driver's code Handle to _HLock.  Doing this is illegal at interrupt time, because the Memory Manager is not reentrant.  Most noticeably, a foreground app relying on MemError() stands a risk to miss errors when the shared RAMdisk is remotely accessed, or if a sound is playing from a file on the RAMdisk (using SndStartFilePlay), because each access to the RAMdisk clears the global MemErr.
  14.  
  15. By contrast, physical disks (and AppleShare) drivers are installed with the dRamBased bit clear, which makes them immune to this particular problem.
  16.  
  17. The solution is to modify how the driver is installed : clear the dRamBased bit in the dCtlFlags field of the DCtlEntry, and change the dCtlDriver field from a Handle to a Pointer; also the DCtlEntry must be locked.  I tried this for using a debugger and is fixes the problem.  As an aside benchmarks of the emulated disk are noticeably improved.
  18. __________________________________________________
  19.  
  20. • DriverInstall
  21. DriverInstall changed to myDriverInstall.  Universal Headers 2.0 now contains a definition for DriverInstall, and we don't want to create confusion in naming.
  22. __________________________________________________
  23.  
  24. • DriverRemove
  25. DriverRemove changed to myDriverRemove.  Universal Headers 2.0 now contains a definition for DriverRemove, and we don't want to create confusion in naming.
  26. __________________________________________________
  27.  
  28. • GetUnusedDrvrRefNum (suggested by Matthew E. Axsom)
  29. The problem occurs in the following lines of code:
  30.  
  31. > while ((unitTable[unitNumber] != nil) && (unitNumber < unitEntryCount)) 
  32. >  ++unitNumber;
  33. >
  34. > if (unitTable[unitNumber] == nil)       /* Find an empty entry? */ 
  35. >  /* Yes, then calculate its driver reference number */ 
  36. >  drvrRefNum = -1 * (unitNumber +1);
  37.  
  38. The above code works just fine as long as the unit table has at least 1 empty slot in it.  If the unit table is completely full, i.e., no empty slots then this section of code can produce an invalid drvrRefNum.  I believe that if the table is full that the routine should return 0 (zero) and then grow the unit table and try again.  Instead, here's what can happen if the unit table is completely full:
  39.  
  40. If there are no empty slots in the unit table then eventually unitNumber will be >= unitEntryCount and the 'while' loop will terminate with unitNumber equal to unitEntryCount.  Since there are only unitEntryCount-1 entries in the unit table, unitNumber now contains an "out of bounds" index for the unit table. After falling out of the 'while' loop, the 'if' statement then uses the "out of bounds" unitNumber for indexing into unitTable.  At this point if the address pointed to by unitTable[unitNumber] is nil then we get a "valid" drvrRefNum which is really invalid because unitNumber is "out of bounds".  What should happen is that the table is full and a drvrRefNum of 0 (zero) be returned so the unit table can be grown.
  41.  
  42. Since I needed to load a driver, I corrected the code this way:
  43.  
  44. > while (unitNumber < unitEntryCount) {
  45. >  if (unitTable[unitNumber] == nil) { /* Find an empty entry? */ 
  46. >     /* Yes, then calculate its driver reference number */ 
  47. >     drvrRefNum = -1 * (unitNumber +1);
  48. >     break;
  49. >  }
  50. >  else
  51. >     ++unitNumber;
  52. > }
  53.  
  54. I tested this out and, as far as I can tell, it works.  It correctly detects a full unit table and returns 0.  The calling routine then grows the unit table and tries again, this time with success.
  55. __________________________________________________
  56.  
  57. • GetUnitEntryCount
  58. Changed to use new definition in Universal Headers 2.0.
  59. __________________________________________________
  60.  
  61. • SetUnitEntryCount
  62. Changed to use new definition in Universal Headers 2.0.
  63. __________________________________________________
  64.  
  65. • All three Metrowerks Projects
  66. I added the keyword STR# resource from "Toasty's Keyword Resources", which can be found on the Internet at sumex-aim.stanford.edu and  various other online services. This new STR# gives highlighting to  all Apple defined keywords.  (Default is green)
  67. __________________________________________________
  68.